<template>
  <div class="config-manager" :class="{style3d: switchStyleConf.chose === '3d'}">
    <div class="config-manager-title">
      <span>工作空间</span>
      <b>随意切换：个人 | 公司 / pc | 移动端</b>
      <InlineRadio :conf="switchConf" v-if="switchConf.list && switchConf.list.length"/>
      <InlineRadio :conf="switchStyleConf"/>
      <CheckBox :conf="checkCodeConf"/>
      <div class="input-simple">
        <input type="text" v-model="userName" placeholder="切换用户">
      </div>
      <div>
        <span @click="applySetting" :class="{loading: isApplyingSetting}">
          检出仓库
        </span>
        <span @click="installDependence" :class="{loading: isInstallingDependence}">安装依赖</span>
        <span @click="openGitStatus" :class="{loading: isGitCommittingAll}">git状态</span>
        <span @click="openDir">文件夹</span>
        <span @click="openCMD" v-if="['win32', 'win64'].includes(osPlatform)">控制台</span>
      </div>
    </div>
    <SwitchWorkSpace :conf="switchWorkSpaceConf"/>
    <div class="config-manager-list">
      <div class="config-manager-inner">
        <SwitchRepertory :conf="switchRepertoryConf" :styleConf="switchStyleConf" v-if="devToolWorkspaceGetCurrent"/>
      </div>
    </div>
    <div class="logs">
      <ul><li v-for="(item, index) in serveMsg" :key="index">{{item}}</li></ul>
    </div>
    <PlatPopup :conf="popConf">
      <BranchForm :conf="popConf"/>
    </PlatPopup>
    <PlatPopup :conf="gitStatusConf">
      <GitStatus :conf="gitStatusConf" :userName="userName"/>
    </PlatPopup>
    <MsgListPop :conf="msgListPopConf"/>
  </div>
</template>
<script>

import devAjax from "../../devAjax";
import PlatformTree from "../../units/PlatformTree";
import PlatPopup from "../../units/PlatPopup";
import InlineRadio from "../../components/InlineRadio";
import CheckBox from "../../components/CheckBox";

import BranchForm from "../../units/BranchForm";
import GitStatus from "../../units/GitStatus";
import MsgListPop from "../../units/MsgListPop";

import SwitchWorkSpace from "./Devs/SwitchWorkSpace";
import SwitchRepertory from "./Devs/SwitchRepertory";

function makeTimeout(fn) {
  let time = `${Date.now()}_${Math.random()}`;
  return function () {
    const thisTime = time = `${Date.now()}_${Math.random()}`;
    const arg = arguments
    setTimeout(function () {
      thisTime === time && fn.apply(null, arg)
    }, 300)
  }
}

const watchUserNameChange = makeTimeout(scope => scope.getdevToolWorkspaceGetCurrent());

export default {
  name: 'home',
  components: {
    CheckBox, SwitchWorkSpace, PlatformTree, PlatPopup, BranchForm, GitStatus,
    SwitchRepertory, InlineRadio, MsgListPop
  },
  data() {
    return {
      userName: localStorage.userName || '',
      osPlatform: 'darwin',
      checkCodeConf: {
        list: [
          {name: '更新别名', isActive: true, code: 'updateAlias'},
          {name: '更新入口文件', isActive: true, code: 'copyFile'},
        ]
      },
      msgListPopConf: {
        show: false,
        title: "消息列表",
        noneMsg: [{msg: 'operation success!', type: 'succ'}],
        footBtn: [
          {name: "知道了", click: (hide, conf) => hide()}
        ],
        list: [],
      },
      switchConf: {
        chose: localStorage.devLocation,
        list: null,
      },
      switchStyleConf: {
        chose: localStorage.devTheme,
        list: [{name: "normal", id: "normal"}, {name: "3d", id: "3d"}],
      },
      serveMsg: [],
      isGitCommittingAll: false,
      isGettingLatestCodes: false,
      isApplyingSetting: false,
      isInstallingDependence: false,
      oriWorkSpaces: [],
      devToolWorkspaceGetCurrent: null,
      gitStatusConf: {
        reInit: () => this.openGitStatus(),
        showMsgPop: list => {
          this.msgListPopConf.list = list && list.length ? list : [{type: 'succ', msg: ''}];
          this.msgListPopConf.show = true;
        },
        status: null,
        workSapce: null,
        show: false,
        full: true,
        onConfirm: branch => {
          this.gitStatusConf.hide();
        },
      },
      popConf: {
        show: false,
        full: true,
        space: null,
        branch: null,
        brances: null,
        onConfirm: branch => {
          const repertory = this.popConf.space;
          const {switchRepertoryConf} =this;
          const {setTarBranches, setAllTarBranches} = switchRepertoryConf;
          repertory ? setTarBranches(repertory, branch) : setAllTarBranches(branch);
          this.popConf.hide();
        },
      },
    }
  },
  computed: {
    workSpaces(){
      const group = this.switchConf.chose;
      return this.oriWorkSpaces.filter(space =>
        space.dto.group === group
      );
    },
    switchRepertoryConf() {
      return {
        workSpaces: this.workSpaces,
        currentWorkspace: this.devToolWorkspaceGetCurrent,
        setMain: space => this.devToolWorkspaceGetCurrent.dto.mainRepertory = space.name,
        openUrl: space => this.openUrl(space),
        showChooseBranch: space => this.showChooseBranch(space),
        setDevWorkspace: workspace => this.setdevToolWorkspaceGetCurrent(workspace),
        openMergeRequestPage: (space, targetBrance) => this.openMergeRequestPage(space, targetBrance),
      }
    },
    switchWorkSpaceConf() {
      return {
        workSpaces: this.workSpaces,
        currentWorkspace: this.devToolWorkspaceGetCurrent,
        setDevWorkspace: workspace => this.setdevToolWorkspaceGetCurrent(workspace),
      }
    },
    unChoseList() {
      const space = this.devToolWorkspaceGetCurrent;
      if (space) return space.dto.repertoryList.filter(item => item.disabled);
    },
    choseList() {
      const space = this.devToolWorkspaceGetCurrent;
      if (space) return space.dto.repertoryList.filter(item => !item.disabled);
    },
  },
  mounted() {
    devAjax.devToolOsPlatform().then(res => this.osPlatform = res.data).catch(e => console.log(e));
    this.getdevToolWorkspaceGetCurrent();
    socketCallback.applySettingSuccess = res => {
      const workspace = this.devToolWorkspaceGetCurrent;
      const {oriWorkSpaces} = this;
      this.devToolWorkspaceGetCurrent = this.initWorkSpaceList(res.workspace)[0];
      this.msgListPopConf.list = res.msgs;
      this.msgListPopConf.show = true;
      oriWorkSpaces.splice(oriWorkSpaces.indexOf(workspace), 1, this.devToolWorkspaceGetCurrent);
      this.isApplyingSetting = false;
      this.serveMsg.push("应用配置成功！");
    };
    socketCallback.applySettingFail = () => this.isApplyingSetting = false;
    socketCallback.applySettingData = res => this.serveMsg.push(res);

    socketCallback.installDependenceSuccess = () => {
      this.serveMsg.push("安装依赖成功！");
      this.isInstallingDependence = false;
    };
    socketCallback.installDependenceFail = () => this.isInstallingDependence = false;
    socketCallback.installDependenceData = res => this.serveMsg.push(res);

    socketCallback.gitCommitAllSuccess = () => {
      this.serveMsg.push("提交代码成功！");
      this.isGitCommittingAll = false;
    };
    socketCallback.gitCommitAllFail = () => this.isGitCommittingAll = false;
    socketCallback.gitCommitAllData = res => this.serveMsg.push(res);
  },
  methods: {
    openGitStatus() {
      devAjax.devToolGitStatus({workspace: this.devToolWorkspaceGetCurrent.name}).then(res => {
        this.gitStatusConf.status = res.data.data;
        this.gitStatusConf.show = true;
        this.gitStatusConf.workSapce = this.devToolWorkspaceGetCurrent.name;
      });
    },
    openMergeRequestPage(space, targetBrance = `master`) {
      if (space && space.id) {
        window.open(
          `${space.repertory.replace(/\.git/, ``)}/merge_requests/new?` +
          `utf8=%E2%9C%93&` +
          `merge_request[source_project_id]=${space.id}&` +
          `merge_request[source_branch]=${space.branch.cur}&` +
          `merge_request[target_project_id]=${space.id}&` +
          `merge_request[target_branch]=${targetBrance}`
        );
      }
    },
    openUrl(space) {
      window.open(space.repertory);
    },
    openDir() {
      devAjax.devToolOpenDir({workspace: this.devToolWorkspaceGetCurrent.name}).then(res => console.log(res));
    },
    openCMD() {
      devAjax.devToolOpenCMD({workspace: this.devToolWorkspaceGetCurrent.name}).then(res => console.log(res));
    },
    applySetting() {
      if (this.isApplyingSetting) return;
      const workspace = this.devToolWorkspaceGetCurrent;
      const sentData = JSON.parse(JSON.stringify(workspace));
      sentData.dto.repertoryList.forEach(item => {delete item.brance});
      if (!sentData.dto.repertoryList.some(item => !item.disabled && item.name === sentData.dto.mainRepertory)) console.log("无主仓库或者贮藏库未激活！");
      this.checkCodeConf.list.forEach(item => (sentData.dto[item.code] = item.isActive));
      sentData.userName = this.userName;
      socket.emit('applySetting', sentData);
      this.isApplyingSetting = true;
    },
    installDependence() {
      if (this.isInstallingDependence) return;
      socket.emit('installDependence', {workspace: this.devToolWorkspaceGetCurrent.name});
      this.isInstallingDependence = true;
    },
    showChooseBranch(space) {
      this.popConf.space = space;
      this.popConf.brances = space && space.branches;
      this.popConf.show = true;
    },
    log() {
      console.log.apply(console, arguments);
    },
    initWorkSpaceList(list, updateSwitchConfList) {
      const switchConfListMap = [];
      const {switchConf} = this;
      list.forEach(space => {
        const group = space.dto.group;
        switchConfListMap.includes(space.dto.group) || switchConfListMap.push(group);
        space.dto.repertoryList.forEach(item => {
          const cur = item.branches && item.branches.current ||"master";
          const prevBranch = item.branch;
          item.branch = {
            cur: cur,
            ori: {branch: `master`, isLocked: !!(prevBranch && prevBranch.ori && prevBranch.ori.isLocked)},
            tar: {branch: cur, isLocked: !!(prevBranch && prevBranch.tar && prevBranch.tar.isLocked)},
          };
          item.disabled = !!item.disabled
        })
      });
      updateSwitchConfList && (switchConf.list = switchConfListMap.map(item => ({name: item, id: item})));
      return list;
    },
    setdevToolWorkspaceGetCurrent(workspace) {
      devAjax.devToolWorkspaceSetCurrent({workspace: workspace.name, userName: this.userName}).then(res => {
        const {oriWorkSpaces} = this;
        this.devToolWorkspaceGetCurrent = this.initWorkSpaceList(res.data.data)[0];
        oriWorkSpaces.splice(oriWorkSpaces.indexOf(workspace), 1, this.devToolWorkspaceGetCurrent);
      });
    },
    getdevToolWorkspaceGetCurrent() {
      localStorage.userName = this.userName
      devAjax.devToolWorkspaceGetCurrent({userName: this.userName}).then(res => {
        const {list, currentEntry} = res.data.data;
        this.oriWorkSpaces = this.initWorkSpaceList(list, true);
        console.log(list.find(item => item.name === currentEntry));
        this.devToolWorkspaceGetCurrent = list.find(item => item.name === currentEntry);
      });
    },
  },
  watch: {
    userName(){
      watchUserNameChange(this);
    },
    "switchConf.chose"(){
      localStorage.devLocation = this.switchConf.chose;
    },
    'switchStyleConf.chose'(){
      localStorage.devTheme = this.switchStyleConf.chose;
    },
    devToolWorkspaceGetCurrent(){
      const conf = this.devToolWorkspaceGetCurrent;
      if (conf) {
        this.checkCodeConf.list[0].isActive = conf.dto.updateAlias;
        this.checkCodeConf.list[1].isActive = conf.dto.copyFile;
      }
    }
  },
}
</script>

<style scoped>
  .drop-wrap{
    padding: 10px;
  }
  .config-manager-list {
    flex: 1 1 0;
    overflow: hidden;
    perspective: 500px;
    background-color: #000;
  }

  .config-manager-list > div {
    width: 100%;
    height: 100%;
  }
  .config-manager.style3d .config-manager-list > div {
    transform: translate3d(0, 0, -300px);
  }

  .config-manager-list > div::-webkit-scrollbar {
    background: transparent;
  }

  .config-manager {
    background-color: #fff;
    height: 100%;
    display: flex;
    flex-direction: column;
    padding: 20px;
  }

  .config-manager-title {
    display: flex;
    border-left: 3px solid #0099cc;
    line-height: 30px;
    margin-bottom: 20px;
  }

  .config-manager-title > span {
    padding: 0 10px;
    font-size: 14px;
  }

  .config-manager-title > b {
    color: #ccc;
    font-size: 12px;
    font-weight: normal;
  }

  .config-manager-title > div {
    flex: 1 1 0;
    text-align: right;
  }

  .config-manager-title > div > span {
    display: inline-block;
    line-height: 24px;
    margin: 4px;
    background-color: #2870ba;
    color: #fff;
    padding: 0 20px;
    border-radius: 4px;
  }

  .config-manager-inner {
    display: flex;
    perspective: 300px;
  }

  .switch-foot-btn {
    display: flex;
    flex-direction: column;
    flex: 0 0 auto;
    max-width: 200px;
    justify-content: center;
    border-top: 1px solid #f8f8f8;
    padding: 10px;
  }

  .switch-foot-btn > span {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 4px 10px;
    margin: 6px 0;
    color: rgba(255, 255, 255, .6);
    border-radius: 2px;
    background-color: #2870ba;
    cursor: pointer;
    transition: all .3s;
  }

  span.loading {
    animation: loading 1s infinite alternate;
  }

  .switch-foot-btn > span:hover {
    color: rgba(255, 255, 255, 1);
  }

  @keyframes loading {
    0% {
      color: rgba(255, 255, 255, 1);
      background-color: #2870ba;
    }
    100% {
      color: #2870ba;
      background-color: #fff;
    }
  }

  .logs {
    width: 100%;
    height: 100px;
    overflow: hidden;
    background-color: #fff;
    position: relative;
  }

  .logs > ul {
    position: absolute;
    bottom: 0;
    left: 0;
  }

  .logs > ul > li {
    padding: 4px 10px;
  }
  div.input-simple{
    flex: 0 0 100px;
    display: flex;
    padding: 2px 0px;
    flex-wrap: wrap;
    justify-content: flex-start;
    align-items: center;
  }
  .input-simple input{
    border: 1px solid var(--cl-major);
    padding: 4px 10px;
    line-height: 20px;
  }
</style>
